﻿using System.Collections.Immutable;
using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class MetadataStyleProperty : Declaration
{
    private SyntaxList<MetadataProperty>? _properties;
    private Expression? _value;

    internal MetadataStyleProperty(SyntaxNode? parent, Identifier identifierName) :
        base(SyntaxKinds.MetadataStyle, SyntaxToken.Default, identifierName, parent)
    {
    }


    protected override bool WithoutDeclareKeywordToken => true;


    /// <summary>
    ///     如果样式属性是单个值，此属性返回已有值。
    /// </summary>
    public Expression? Value => _value;


    /// <summary>
    ///     如果配置格式类似
    ///     <code>
    ///         Control ( Accelerator = "R", Type = ListBox )
    ///     </code>
    ///     此方法返回圆括号内的属性配置。
    /// </summary>
    public ImmutableArray<MetadataProperty> GetProperties()
    {
        return _properties?.ToImmutableArray() ?? ImmutableArray<MetadataProperty>.Empty;
    }


    /// <summary>
    ///     更新样式属性的直接配置的值
    /// </summary>
    public void Update(Expression? value)
    {
        SetChildNullableField(ref _value, Expression.IsEmptyExpression, value);
    }


    /// <summary>
    ///     添加一个成员属性到属性列表，需要<see cref="Value" />是<see langword="null" />
    /// </summary>
    public void Update(MetadataProperty property)
    {
        Debug.Assert(_value == null || Expression.IsEmptyExpression(_value));
        _properties ??= new SyntaxList<MetadataProperty>();
        _properties.Add(property);
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, NameIdentifier, Value);
        AcceptList(visitor, _properties);
    }
}


public static partial class NodeFactory
{
    public static MetadataStyleProperty CreateMetadataStyleProperty(SyntaxNode? parent, Identifier identifierName,
        Expression value)
    {
        MetadataStyleProperty prop = new(parent, identifierName);
        if (!Expression.IsEmptyExpression(value))
        {
            prop.Update(value);
        }

        return prop;
    }
}